import './form.scss'
import React from 'react';

import { cssPrefix } from '../baseData';

import DatePicker from '../date/Date.jsx';

const isFormItem = (tagName)=>{
  let formItems = ['INPUT', 'TEXTAREA', 'BUTTON', 'SELECT', 'OPTION', 'OPTGROUP', 'FIELDSET', 'LABEL'];

  return formItems.find(item => item==tagName);
}

const { Provider, Consumer } = React.createContext({layout: 'horizontal'});

class _Input extends React.Component{

  render(){
    let { className, type, name, value, checkedValues, placeholder, disabled, readOnly, onChange, onBlur, onKeyUp } = this.props,
      checked = '';
    if((type == 'checkbox' || type == 'radio') && checkedValues){
      checkedValues.constructor == Array
        ? ( checked = checkedValues.find(d => d==value) ? 'checkbox' : '' )
        : ( checked = checkedValues == value ? 'checkbox' : '' )
    }

    readOnly = typeof onChange != 'function' ? true : readOnly;


    return <input
      className={className ? className : ''}
      type={type ? type : 'text'}
      name={name}
      value={value == null ? '' : value}
      placeholder={placeholder}
      disabled={disabled}
      onChange={onChange && onChange.bind(this, {name})}
      onBlur={onBlur && onBlur.bind(this, {name})}
      onKeyUp={onKeyUp && onKeyUp.bind(this, {name})}
      readOnly={readOnly}
      checked={checked}
    />
  }
}

class Input extends React.Component{
  constructor(props){
    super(props);
    this.change = this.change.bind(this);
  }
  change(props, e){

    let { onChange } = this.props,
      isForm = isFormItem(e.target.tagName);

    isForm && (props.value = e.target.value);

    if(e.target.tagName == 'SPAN' || isForm){
      typeof onChange == 'function' && onChange(props, e);
    }

    e.target.tagName == 'SPAN' && e.currentTarget.querySelectorAll('input')[0].focus();
  }
  render(){
    let { type, name, disabled } = this.props;

    !type && (type = 'text');

    if(type == 'text' || type == 'password'){
      return <div className={`${cssPrefix}input-wrap`} onClick={this.change.bind(this, {name, value: ''})} >
        <_Input {...this.props} type={type} onChange={this.change} />
        {
          !disabled && <span className={`${cssPrefix}icon-close`}></span>
        }
      </div>
    }else{
      return <_Input {...this.props} type={type} onChange={this.change} />
    }
  }
}

class Select extends React.Component{
  render(){
    let { className, name, value, options, placeholder, disabled, onChange } = this.props;
    return <select
      className={className ? className : ''}
      name={name}
      value={value == null ? '' : value}
      placeholder={placeholder}
      disabled={disabled}
      readOnly={onChange ? false : true}
      onChange={onChange && onChange.bind(this, {name})}>
      { this.props.children }
      {
        options && options.map((option, index)=>{
          return <option key={index} value={option.value == null ? '' : option.value}>{option.text ? option.text : option.value}</option>
        })
      }
    </select>
  }
}

class Textarea extends React.Component{
  change(props, e){
    let { onChange } = this.props;

    props.value = e.target.value;

    typeof onChange == 'function' && onChange(props, e)
  }
  render(){
    let { className, name, value, placeholder, disabled, readOnly, onBlur, onKeyUp, resize } = this.props;
    return <textarea
      className={className ? className : ''}
      name={name}
      value={value == null ? '' : value}
      placeholder={placeholder}
      disabled={disabled}
      onChange={this.change.bind(this, {name})}
      onBlur={onBlur && onBlur.bind(this, {name})}
      onKeyUp={onKeyUp && onKeyUp.bind(this, {name})}
      readOnly={readOnly}
      style={{resize: resize ? resize : 'both'}}    // resize: none|both|horizontal|vertical;
    />
  }
}

class Radio extends React.Component{
  render(){
    let { className, label } = this.props;

    !className && (className = '');
    className += ` ${cssPrefix}radio-wrap`;
    return <label
      className={className}
    >
      <Input type={'radio'} {...this.props} />
      <span>{label}</span>

    </label>
  }
}

class Radios extends React.Component{
  render(){
    let { radios } = this.props;

    return <div className={`${cssPrefix}radio-group`}>
      {
        radios.map((item,key)=>{
          let props = {...this.props,...item}
          return <Radio key={key} {...props} />
        })
      }
    </div>

  }
}

class Checkbox extends React.Component{
  render(){
    let { className, label } = this.props;

    !className && (className = '');
    className += ` ${cssPrefix}checkbox-wrap`;
    return <label
      className={className}
    >
      <Input type={'checkbox'} {...this.props} />
      {
        label && <span>{label}</span>
      }
    </label>
  }
}

class Checkboxs extends React.Component{
  render(){
    let { checkboxs } = this.props;

    return <div className={`${cssPrefix}checkbox-group`}>
      {
        checkboxs.map((item,key)=>{
          let props = {...this.props,...item}
          return <Checkbox key={key} {...props} />
        })
      }
    </div>
  }
}

class FormItem extends React.Component {
  render(){
    return <Consumer>
      {
        (data)=>{

          let props = {...data, ...this.props},
            { layout, className, label, formType, span, required, explain, hasError, errorInfo, width } = props;
          !className && (className = '');

          className += ` ${cssPrefix}form-item clearfix`;

          layout == 'horizontal' && !span && (span = 20);

          return <div className={className}>
            {
              label && <label className={`${cssPrefix}form-item-label${layout == 'horizontal' ? ` ${cssPrefix}col-${24-span}` : ''}${required ? ` ${cssPrefix}form-item-required` : ''}`}>
                {label}:
              </label>
            }
            {
              formType && <div style={{width: width}} className={`${cssPrefix}form-item-control${layout == 'horizontal' ? ` ${cssPrefix}col-${span}` : ''}${hasError ? ` ${cssPrefix}form-item-has-error` : ''}`}>
                {
                  formType == 'input' && <Input {...this.props} />
                }
                {
                  formType == 'select' && <Select {...this.props} />
                }
                {
                  formType == 'textarea' && <Textarea {...this.props} />
                }
                {
                  formType == 'checkbox' && <Checkbox {...this.props} />
                }
                {
                  formType == 'checkboxs' && <Checkboxs {...this.props} />
                }
                {
                  formType == 'radio' && <Radio {...this.props} />
                }
                {
                  formType == 'radios' && <Radios {...this.props} />
                }
                {
                  formType == 'date' && <DatePicker {...this.props.date} />
                }
                {
                  (explain || errorInfo) && <div className={`${cssPrefix}form-item-explain`} >{hasError ? errorInfo : explain}</div>
                }
              </div>
            }

            {this.props.children}
          </div>
        }
      }
    </Consumer>
  }
}

class InlineFormItem extends React.Component {
  render(){


    let { className, label, formType, span, required, explain, hasError, errorInfo, width } = this.props;
    !className && (className = '');

    className += ` ${cssPrefix}form-item-inline`;

    return <div className={className}>
      {
        label && <label className={`${cssPrefix}form-item-inline-label`}>
          {label}:
        </label>
      }
      {
        formType && <div style={{width: width}} className={`${cssPrefix}form-item-inline-control${hasError ? ` ${cssPrefix}form-item-has-error` : ''}`}>
          {
            formType == 'input' && <Input {...this.props} />
          }
          {
            formType == 'select' && <Select {...this.props} />
          }
          {
            formType == 'textarea' && <Textarea {...this.props} />
          }
          {
            formType == 'checkbox' && <Checkbox {...this.props} />
          }
          {
            formType == 'checkboxs' && <Checkboxs {...this.props} />
          }
          {
            formType == 'radio' && <Radio {...this.props} />
          }
          {
            formType == 'radios' && <Radios {...this.props} />
          }
          {
            formType == 'date' && <DatePicker {...this.props.date} />
          }
          {
            (explain || errorInfo) && <div className={`${cssPrefix}form-item-explain`} >{hasError ? errorInfo : explain}</div>
          }
        </div>
      }
    </div>
  }
}

class FormGroup extends React.Component{
  render(){
    let { className, layout } = this.props;

    !className && (className = '');

    className += ` ${cssPrefix}form-group`;

    layout && (className += ` ${cssPrefix}form-group-${layout}`);

    return <div className={className}>
      <Provider value={this.props}>
        {this.props.children}
      </Provider>
    </div>
  }
}

module.exports = {
  Input,
  Select,
  Textarea,
  Radio,
  Radios,
  Checkbox,
  FormItem,
  InlineFormItem,
  FormGroup
}